package org.budo.support.log4j.configurator;

import java.net.URL;

import org.apache.log4j.LogManager;
import org.apache.log4j.helpers.Loader;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.xml.DOMConfigurator;
import org.budo.support.lang.util.StringUtil;
import org.budo.support.lang.util.SystemUtil;
import org.budo.support.slf4j.Slf4j;
import org.slf4j.Logger;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;

/**
 * @author lmw
 */
public class OnContextRefreshedEventLog4jConfigurator implements ApplicationListener<ApplicationEvent> {
    private static final String LOG4J_XML_KEY = "log4jXml";

    private static final Logger log = Slf4j.getLogger();

    private String lastConf = "log4j.xml";

    private String log4jXml = "log4j-online.xml";

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        if (event instanceof ContextRefreshedEvent) {
            try {
                String log4jXmlConf = SystemUtil.getEnvOrProperty(LOG4J_XML_KEY);

                String conf;
                if (!StringUtil.isEmpty(log4jXmlConf) && !"null".equalsIgnoreCase(log4jXmlConf)) {
                    conf = log4jXmlConf; // System#Property 优先
                } else {
                    conf = this.getLog4jXml(); // 使用项目中Bean的配置
                    LogLog.warn("#40 before reload log4j conf, conf=" + conf);
                }

                // 新的配置与当前相同，不重新加载
                if (null != lastConf && lastConf.equals(conf)) {
                    LogLog.warn("#45 same conf, skip, conf=" + conf + ", lastConf=" + this.lastConf);
                    return;
                }

                URL url = Loader.getResource(conf);
                if (null == url) {
                    LogLog.error("#51 conf not exists, conf=" + conf + ", lastConf=" + this.lastConf);
                    return;
                }

                // 重新加载配置
                this.lastConf = conf;
                LogLog.warn("#49 doing reload log4j conf, log4jXmlConf=" + log4jXmlConf + ", conf=" + conf + ", lastConf=" + this.lastConf);

                LogManager.resetConfiguration(); // 清空旧的配置

                DOMConfigurator.configure(url); // 加载新的配置

                LogLog.warn("#57 done reload log4j conf, conf=" + conf);
            } catch (Exception e) {
                LogLog.error("#59 reload log4j conf error, e=" + e);
                log.error("#60 reload log4j conf error", e);
            }
        }
    }

    public String getLog4jXml() {
        return this.log4jXml;
    }

    public void setLog4jXml(String log4jXml) {
        this.log4jXml = log4jXml;
    }
}
